package com.sjm.learn.multithreading;

/**
 * @Description:synchronized, wait, notify结合:典型场景生产者消费者问题
 * @Author：shenjm25081
 * @Date：17:37 2019-2-20
 */
public class MultithreadingDemo2 {

    private volatile int product = 0;
    private static int MAX_PRODUCT = 20;
    private static int MIN_PRODUCT = 5;

    /**
     * 生产者生产出来的产品交给店员
     */
    public synchronized void produce()
    {
        if(this.product >= MAX_PRODUCT)
        {
            try
            {
                System.out.println("产品已满,请稍候再生产");
                wait();
                System.out.println("准备再生产啦");
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
            return;
        }
        this.product++;
        System.out.println("生产者生产第" + this.product + "个产品.");
        notifyAll();   //通知等待区的消费者可以取出产品了
    }

    /**
     * 消费者从店员取产品
     */
    public synchronized void consume()
    {
        if(this.product <= MIN_PRODUCT)
        {
            try
            {
                System.out.println("缺货,稍候再取");
                wait();
                System.out.println("准备取货啦");
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            return;
        }

        System.out.println("消费者取走了第" + this.product + "个产品.");
        this.product--;
        notifyAll();   //通知等待区的生产者可以生产产品了
    }

    public static void main(String[] args){
        final MultithreadingDemo2 demo = new MultithreadingDemo2();
        Thread[] threads = new Thread[2];
        threads[0] = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 30; i++) {
                    demo.produce();
                }
            }
        });
        threads[1] = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 30; i++) {
                    demo.consume();
                }
            }
        });
        threads[0].start();
        threads[1].start();
    }
}
